package com.xy.service.order;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xy.api.exception.BizException;
import com.xy.api.model.dto.mainData.LogisticalDTO;
import com.xy.api.model.dto.mainData.ProductDTO;
import com.xy.api.model.dto.mainData.VendorDTO;
import com.xy.api.model.dto.mainData.VendorProductTypeDTO;
import com.xy.api.model.dto.order.PlaceFollowOrderDTO;
import com.xy.api.model.request.order.PFORequest;
import com.xy.api.model.response.Rows;
import com.xy.api.service.mainData.ILogisticalService;
import com.xy.api.service.mainData.IVendorProductTypeService;
import com.xy.api.service.mainData.IVendorService;
import com.xy.api.service.order.IPlaceFollowOrderService;
import com.xy.auth.UserContext;
import com.xy.mapper.order.PlaceFollowOrderMapper;
import com.xy.model.po.order.PlaceFollowOrderPO;
import com.xy.utils.CustomBeanUtil;
import com.xy.utils.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class PlaceFollowOrderServiceImpl implements IPlaceFollowOrderService {

    @Autowired
    private PlaceFollowOrderMapper placeFollowOrderMapper;

    @Autowired
    private IVendorService vendorService;

    @Autowired
    private ILogisticalService logisticalService;

    @Autowired
    private IVendorProductTypeService vendorProductTypeService;

    @Override
    public Rows<PlaceFollowOrderDTO> queryPlaceFollowOrderList(PFORequest request) {
        Rows<PlaceFollowOrderDTO> result = new Rows<>();
        LambdaQueryWrapper<PlaceFollowOrderPO> placeFollowOrderWrapper = new LambdaQueryWrapper<>();
        placeFollowOrderWrapper.eq(PlaceFollowOrderPO::getIsDeleted, 0);
        if (StringUtils.hasText(request.getPoP())) {
            placeFollowOrderWrapper.like(PlaceFollowOrderPO::getPoP, "%" + request.getPoP() + "%");
        }
        if (StringUtils.hasText(request.getPoC())) {
            placeFollowOrderWrapper.like(PlaceFollowOrderPO::getPoC, "%" + request.getPoC() + "%");
        }
        int pageSize = null != request.getPageSize() ? request.getPageSize() : 10;
        int pageNum = null != request.getPageNum() ? request.getPageNum() : 1;
        Page<PlaceFollowOrderPO> placeFollowOrderPOPage = new Page<>(pageNum, pageSize);
        placeFollowOrderPOPage = placeFollowOrderMapper.selectPage(placeFollowOrderPOPage, placeFollowOrderWrapper);

        List<PlaceFollowOrderDTO> placeFollowOrderList = CustomBeanUtil.copyListProperties(placeFollowOrderPOPage.getRecords(), PlaceFollowOrderDTO::new);
        fillVendor(placeFollowOrderList);
        fillLogistical(placeFollowOrderList);
        result.setTotal(placeFollowOrderPOPage.getTotal());
        result.setRows(placeFollowOrderList);
        return result;
    }

    /**
     * 填充VendorName
     *
     * @param list
     */
    private void fillVendor(List<PlaceFollowOrderDTO> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<Long> vendorIds = list.stream().map(e -> e.getVendorId()).distinct().collect(Collectors.toList());
        Map<Long, VendorDTO> vendorMap = vendorService.getVendorByIds(vendorIds);
        for (PlaceFollowOrderDTO placeFollowOrder : list) {
            Long vendorId = placeFollowOrder.getVendorId();
            if (vendorMap.containsKey(vendorId)) {
                VendorDTO vendor = vendorMap.get(vendorId);
                placeFollowOrder.setVendorName(vendor.getName());
            }
        }
    }

    /**
     * 填充VendorName
     *
     * @param placeFollowOrder
     */
    private void fillVendor(PlaceFollowOrderDTO placeFollowOrder) {
        VendorDTO vendor = vendorService.vendorDetail(placeFollowOrder.getVendorId());
        placeFollowOrder.setVendorName(vendor.getName());
    }

    /**
     * 填充物流商信息
     *
     * @param list
     */
    private void fillLogistical(List<PlaceFollowOrderDTO> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<Long> logisticalIds = list.stream().map(PlaceFollowOrderDTO::getLogisticalId).distinct().collect(Collectors.toList());
        Map<Long, LogisticalDTO> logisticalMap = logisticalService.getLogisticalByIds(logisticalIds);

        for (PlaceFollowOrderDTO placeFollowOrder : list) {
            Long logisticalId = placeFollowOrder.getLogisticalId();
            if (logisticalMap.containsKey(logisticalId)) {
                LogisticalDTO logistical = logisticalMap.get(logisticalId);
                placeFollowOrder.setLogisticalName(logistical.getName());
            }
        }
    }

    @Override
    public PlaceFollowOrderDTO placeFollowOrderDetail(Long id) {
        PlaceFollowOrderDTO result = queryById(id);
        Integer oneBatch = null == result.getBatchSecond() ? 1 : 0;
        result.setOneBatch(oneBatch);
        fillVendor(result);
        fillVendorType(result);
        return result;
    }

    private void fillVendorType(PlaceFollowOrderDTO placeFollowOrder) {
        if (null == placeFollowOrder.getVendorProductTypeId()) {
            return;
        }
        VendorProductTypeDTO vendorProductType = vendorProductTypeService.vendorProductTypeDetail(placeFollowOrder.getVendorProductTypeId());
        placeFollowOrder.setVendorProductTypeName(vendorProductType.getName());
    }

    @Override
    public PlaceFollowOrderDTO queryById(Long id) {
        Assert.notNull(id, "工厂下单跟单ID必填");
        PlaceFollowOrderPO placeFollowOrderPO = placeFollowOrderMapper.selectById(id);
        PlaceFollowOrderDTO result = new PlaceFollowOrderDTO();
        CustomBeanUtil.copyProperties(placeFollowOrderPO, result);
        return result;
    }

    @Override
    public PlaceFollowOrderDTO editPlaceFollowOrder(PlaceFollowOrderDTO request) {
        PlaceFollowOrderPO record = new PlaceFollowOrderPO();
        CustomBeanUtil.copyProperties(request, record);
        // 生成Po-P以及Po-C
        generatePoPAndPoC(record, request.getOneBatch());
        if (null == record.getId()) {
            addPlaceFollowOrder(record);
        } else {
            updatePlaceFollowOrder(record);
        }
        PlaceFollowOrderDTO result = new PlaceFollowOrderDTO();
        CustomBeanUtil.copyProperties(record, result);
        return result;
    }

    /**
     * 生成Po-P以及Po-C
     *
     * @param record
     * @param oneBatch 是否一批全部运走
     */
    private void generatePoPAndPoC(PlaceFollowOrderPO record, Integer oneBatch) {
        checkBeforeGeneratePoPAndPoC(record, oneBatch);

        String orderTimeYearMonthDay = TimeUtil.getYearMonthDay(record.getOrderTime());
        VendorDTO vendor = vendorService.vendorDetail(record.getVendorId());
        if (null == vendor || !StringUtils.hasText(vendor.getCode())) {
            throw new BizException("供应商不存在或供应商CODE为空");
        }
        String vendorCode = vendor.getCode();

        String batchNumber = "01";
        if (record.getBatchNumber() < 10) {
            batchNumber = "0" + record.getBatchNumber();
        }
        VendorProductTypeDTO vendorProductType = vendorProductTypeService.vendorProductTypeDetail(record.getVendorProductTypeId());
        if (null == vendorProductType || !StringUtils.hasText(vendorProductType.getCode())) {
            throw new BizException("供应商产品类型异常");
        }
        String vendorProductTypeCode = vendorProductType.getCode();
        String poP = orderTimeYearMonthDay + vendorCode + vendorProductTypeCode + batchNumber;
        String poC = poP;
        if (!Objects.equals(oneBatch, 1)) {
            poC += "-" + record.getBatchSecond();
        } else {
            record.setBatchSecond(null);
        }
        record.setPoP(poP);
        record.setPoC(poC);
    }

    /**
     * 生成Po-P以及Po-C前的检查
     *
     * @param request
     */
    private void checkBeforeGeneratePoPAndPoC(PlaceFollowOrderPO request, Integer oneBatch) {
        if (null == request.getOrderTime()) {
            throw new BizException("未填写下单日期");
        }
        if (null == request.getVendorId()) {
            throw new BizException("未选择供应商");
        }
        if (null == request.getVendorProductTypeId()) {
            throw new BizException("未选择供应商产品类型");
        }
        if (null == request.getBatchNumber()) {
            throw new BizException("未填写批次");
        }
        if (!Objects.equals(oneBatch, 1) && null == request.getBatchSecond()) {
            throw new BizException("同一个批次的货物分多批发送，未填写第几批");
        }
    }

    private void addPlaceFollowOrder(PlaceFollowOrderPO record) {
        record.setCreateBy(UserContext.get().getId());
        placeFollowOrderMapper.insert(record);
    }

    private void updatePlaceFollowOrder(PlaceFollowOrderPO record) {
        Assert.notNull(record.getId(), "工厂下单跟单ID必填");
        record.setUpdateBy(UserContext.get().getId());
        placeFollowOrderMapper.updateById(record);

        if (null == record.getBatchSecond()) {
            placeFollowOrderMapper.clearBatchSecond(record.getId());
        }
    }

    @Override
    public void deletePlaceFollowOrder(Long id) {
        Assert.notNull(id, "工厂下单跟单ID必填");

        PlaceFollowOrderPO deleteRecord = new PlaceFollowOrderPO();
        deleteRecord.setId(id);
        deleteRecord.setIsDeleted(1);
        deleteRecord.setUpdateBy(UserContext.get().getId());
        placeFollowOrderMapper.updateById(deleteRecord);
    }
}
